// Copyright (c) MatrixFramework. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using MatrixFramework.Core.Results;
using MatrixFramework.Keycloak.Abstractions.Models;
using MatrixFramework.Keycloak.Abstractions.Services;

namespace TenantManagementService.Migration.Services;

/// <summary>
/// 租户管理服务实现（新版 - 使用MatrixFramework.Keycloak）
/// </summary>
public class TenantManagementService : ITenantManagementService
{
    private readonly IKeycloakAdminService _keycloakAdminService;
    private readonly ILogger<TenantManagementService> _logger;

    public TenantManagementService(
        IKeycloakAdminService keycloakAdminService,
        ILogger<TenantManagementService> logger)
    {
        _keycloakAdminService = keycloakAdminService ?? throw new ArgumentNullException(nameof(keycloakAdminService));
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    public async Task<Result<TenantCreationResult>> CreateTenantAsync(TenantInfo tenantInfo, CancellationToken cancellationToken = default)
    {
        try
        {
            _logger.LogInformation("开始创建租户: {TenantId} - {TenantName}", tenantInfo.Id, tenantInfo.Name);

            // 生成Realm名称
            var realmName = GenerateRealmName(tenantInfo.Id);

            // 创建Realm创建信息
            var realmCreationInfo = new RealmCreationInfo
            {
                RealmName = realmName,
                DisplayName = tenantInfo.Name,
                Description = tenantInfo.Description ?? $"租户 {tenantInfo.Name} 的专用Realm",
                Enabled = tenantInfo.Enabled,
                AdminUser = tenantInfo.AdminUser != null ? new UserCreationInfo
                {
                    Username = tenantInfo.AdminUser.Username,
                    Email = tenantInfo.AdminUser.Email,
                    FirstName = tenantInfo.AdminUser.FirstName,
                    LastName = tenantInfo.AdminUser.LastName,
                    Password = tenantInfo.AdminUser.Password,
                    Enabled = true,
                    EmailVerified = true,
                    Roles = new List<string> { "admin", "tenant-admin" }
                } : null,
                Attributes = new Dictionary<string, object>
                {
                    ["tenant_id"] = tenantInfo.Id,
                    ["tenant_name"] = tenantInfo.Name,
                    ["tenant_code"] = tenantInfo.Code,
                    ["created_by"] = "TenantManagementService",
                    ["created_at"] = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ")
                }
            };

            // 创建Realm
            var realmResult = await _keycloakAdminService.CreateRealmAsync(realmCreationInfo, cancellationToken);

            if (realmResult.IsSuccess)
            {
                var result = new TenantCreationResult
                {
                    TenantId = tenantInfo.Id,
                    TenantName = tenantInfo.Name,
                    RealmName = realmResult.Value.RealmName,
                    AdminUsername = realmResult.Value.AdminUsername,
                    AdminPassword = realmResult.Value.AdminPassword,
                    AdminConsoleUrl = realmResult.Value.AdminConsoleUrl,
                    CreatedAt = realmResult.Value.CreatedAt,
                    Success = true,
                    Message = "租户创建成功"
                };

                _logger.LogInformation("租户创建成功: {TenantId}, Realm: {RealmName}", tenantInfo.Id, realmName);
                return Result<TenantCreationResult>.Success(result);
            }
            else
            {
                _logger.LogError("租户创建失败: {TenantId}, 错误: {Error}", tenantInfo.Id, realmResult.GetErrorString());

                var result = new TenantCreationResult
                {
                    TenantId = tenantInfo.Id,
                    TenantName = tenantInfo.Name,
                    Success = false,
                    Message = realmResult.GetErrorString()
                };

                return Result<TenantCreationResult>.Failure(realmResult.GetErrorString());
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "创建租户时发生异常: {TenantId}", tenantInfo.Id);
            return Result<TenantCreationResult>.Failure(ex);
        }
    }

    public async Task<Result> DeleteTenantAsync(string tenantId, CancellationToken cancellationToken = default)
    {
        try
        {
            _logger.LogInformation("开始删除租户: {TenantId}", tenantId);

            var realmName = GenerateRealmName(tenantId);
            var result = await _keycloakAdminService.DeleteRealmAsync(realmName, cancellationToken);

            if (result.IsSuccess)
            {
                _logger.LogInformation("租户删除成功: {TenantId}, Realm: {RealmName}", tenantId, realmName);
                return Result.Success();
            }
            else
            {
                _logger.LogError("租户删除失败: {TenantId}, 错误: {Error}", tenantId, result.GetErrorString());
                return Result.Failure($"租户删除失败: {result.GetErrorString()}");
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "删除租户时发生异常: {TenantId}", tenantId);
            return Result.Failure(ex);
        }
    }

    public async Task<Result<TenantSyncResult>> SyncTenantAsync(string tenantId, CancellationToken cancellationToken = default)
    {
        try
        {
            _logger.LogInformation("开始同步租户: {TenantId}", tenantId);

            // 这里应该从数据库或其他存储中获取租户信息
            // 为了演示，我们创建一个示例租户信息
            var tenantInfo = new TenantInfo
            {
                Id = tenantId,
                Name = $"租户 {tenantId}",
                Code = tenantId,
                Enabled = true,
                Description = $"同步的租户 {tenantId}",
                AdminUser = new UserCreationInfo
                {
                    Username = $"{tenantId}-admin",
                    Email = $"admin@{tenantId}.example.com",
                    FirstName = "Admin",
                    LastName = "User",
                    Password = "TempPassword123!"
                }
            };

            var result = await _keycloakAdminService.SyncTenantAsync(tenantInfo, cancellationToken);

            if (result.IsSuccess)
            {
                _logger.LogInformation("租户同步成功: {TenantId}", tenantId);
                return Result<TenantSyncResult>.Success(result.Value);
            }
            else
            {
                _logger.LogError("租户同步失败: {TenantId}, 错误: {Error}", tenantId, result.GetErrorString());
                return Result<TenantSyncResult>.Failure(result.GetErrorString());
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "同步租户时发生异常: {TenantId}", tenantId);
            return Result<TenantSyncResult>.Failure(ex);
        }
    }

    public async Task<Result<BatchTenantSyncResult>> SyncTenantsAsync(List<string> tenantIds, CancellationToken cancellationToken = default)
    {
        try
        {
            _logger.LogInformation("开始批量同步租户: {Count}个", tenantIds.Count);

            var tenantInfos = tenantIds.Select(tenantId => new TenantInfo
            {
                Id = tenantId,
                Name = $"租户 {tenantId}",
                Code = tenantId,
                Enabled = true,
                Description = $"批量同步的租户 {tenantId}",
                AdminUser = new UserCreationInfo
                {
                    Username = $"{tenantId}-admin",
                    Email = $"admin@{tenantId}.example.com",
                    FirstName = "Admin",
                    LastName = "User",
                    Password = "TempPassword123!"
                }
            }).ToList();

            var result = await _keycloakAdminService.SyncTenantsAsync(tenantInfos, cancellationToken);

            if (result.IsSuccess)
            {
                _logger.LogInformation("批量租户同步成功: {SuccessCount}/{TotalCount}",
                    result.Value.SuccessCount, result.Value.TotalTenants);
                return Result<BatchTenantSyncResult>.Success(result.Value);
            }
            else
            {
                _logger.LogError("批量租户同步失败: {Error}", result.GetErrorString());
                return Result<BatchTenantSyncResult>.Failure(result.GetErrorString());
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "批量同步租户时发生异常");
            return Result<BatchTenantSyncResult>.Failure(ex);
        }
    }

    public async Task<Result<TenantSyncStatus>> GetTenantSyncStatusAsync(string tenantId, CancellationToken cancellationToken = default)
    {
        try
        {
            _logger.LogDebug("获取租户同步状态: {TenantId}", tenantId);

            var result = await _keycloakAdminService.GetTenantSyncStatusAsync(tenantId, cancellationToken);

            if (result.IsSuccess)
            {
                return Result<TenantSyncStatus>.Success(result.Value);
            }
            else
            {
                _logger.LogWarning("获取租户同步状态失败: {TenantId}, 错误: {Error}", tenantId, result.GetErrorString());
                return Result<TenantSyncStatus>.Failure(result.GetErrorString());
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取租户同步状态时发生异常: {TenantId}", tenantId);
            return Result<TenantSyncStatus>.Failure(ex);
        }
    }

    public async Task<Result<bool>> TestTenantConnectionAsync(string tenantId, CancellationToken cancellationToken = default)
    {
        try
        {
            _logger.LogDebug("测试租户连接: {TenantId}", tenantId);

            var realmName = GenerateRealmName(tenantId);
            var result = await _keycloakAdminService.TestRealmConnectionAsync(realmName, cancellationToken);

            if (result.IsSuccess)
            {
                _logger.LogDebug("租户连接测试成功: {TenantId}, Connected: {Connected}", tenantId, result.Value);
                return Result<bool>.Success(result.Value);
            }
            else
            {
                _logger.LogWarning("租户连接测试失败: {TenantId}, 错误: {Error}", tenantId, result.GetErrorString());
                return Result<bool>.Failure(result.GetErrorString());
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "测试租户连接时发生异常: {TenantId}", tenantId);
            return Result<bool>.Failure(ex);
        }
    }

    /// <summary>
    /// 生成Realm名称
    /// </summary>
    /// <param name="tenantId">租户ID</param>
    /// <returns>Realm名称</returns>
    private string GenerateRealmName(string tenantId)
    {
        // 使用租户ID作为Realm名称
        return $"tenant-{tenantId}";
    }
}